const {
  NoPermissionErr,
  NotLoginErr,
  TokenExpireErr,
} = require('../../response/code')
const { verifyToken, redisCheck } = require('../../util/jwt')

const { createRedisClient } = require('../../util/redis')

const { TOKEN_PREFIX } = require('../../consts/system')
/**
 * 校验TOKEN
 * @param {*} ctx
 * @param {*} next
 * @returns
 */
const validateToken = async (ctx, next) => {
  // 取得header信息
  const header = ctx.request.header
  // 取得token信息
  const token = header['authorization']
    ? header['authorization'].split(' ')[1]
    : ''
  if (!token) {
    ctx.app.emit('error', NotLoginErr, ctx)
    return
  }
  const secret = process.env.JWT_SECRET
  const user = verifyToken(token, secret)
  // console.log('token verify user >>>>', JSON.stringify(user))
  if (!user) {
    // token 校验失败
    ctx.app.emit('error', TokenExpireErr, ctx)
    return
  }

  // redis 校验 - 添加错误处理
  try {
    const conn = createRedisClient()
    await conn.connect()
    const redisVal = await conn.get(`${TOKEN_PREFIX}:${user.phone}`)

    // 确保连接关闭，无论成功失败
    try {
      // 兼容不同版本的Redis客户端
      if (conn.close) {
        await conn.close()
      } else if (conn.quit) {
        await conn.quit()
      }
    } catch (closeErr) {
      console.warn('Redis连接关闭失败:', closeErr)
    }

    if (!redisCheck(token, redisVal)) {
      ctx.app.emit('error', TokenExpireErr, ctx)
      return
    }
  } catch (redisError) {
    console.error('Redis校验过程中出错:', redisError)
    // 可以选择在这里直接返回错误，或者让应用继续尝试
    // ctx.app.emit('error', new SysErr('Redis连接失败', redisError), ctx)
    // return
  }

  // 校验
  ctx.state.user = user
  //
  await next()
}

/**
 * 校验是否是管理员
 * @param {*} ctx
 * @param {*} next
 * @returns
 */
const validateAdmin = async (ctx, next) => {
  const user = ctx.state.user
  if (!user) {
    return ctx.app.emit('error', NotLoginErr, ctx)
  }
  if (user.id === 0 || user.id === '') {
    return ctx.app.emit('error', NoPermissionErr, ctx)
  }
  await next()
}

module.exports = {
  validateToken,
  validateAdmin,
}
